package com.hit.server.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hit.server.api.entity.CheckPositionEntity;
import com.hit.server.api.dto.CheckPositionQueryDTO;
import com.hit.server.api.dto.CheckPositionSaveDTO;
import com.hit.server.api.dto.CheckPositionUpdateDTO;
import com.hit.server.api.entity.CheckPositionStandardEntity;
import com.hit.server.api.entity.CheckStandardEntity;
import com.hit.server.api.entity.RobotEntity;
import com.hit.server.api.service.CheckPositionStandardService;
import com.hit.server.api.vo.CheckPositionVO;
import com.hit.server.biz.mapper.CheckPositionMapper;
import com.hit.server.api.service.CheckPositionService;
import com.hit.server.biz.mapper.CheckPositionStandardMapper;
import com.hit.server.biz.mapper.CheckStandardMapper;
import com.hit.server.biz.mapper.RobotMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import lombok.RequiredArgsConstructor;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 检测点位
 *
 * @author kehanjiang
 * @date 2025-04-15 16:49:33
 */
@Service
@RequiredArgsConstructor
public class CheckPositionServiceImpl extends ServiceImpl<CheckPositionMapper, CheckPositionEntity> implements CheckPositionService {

    private final RobotMapper robotMapper;

    private final CheckPositionStandardService checkPositionStandardService;

    private final CheckStandardMapper checkStandardMapper;

    private CheckPositionVO convertToVO(Object o) {
        if (o instanceof CheckPositionEntity) {
            CheckPositionVO vo = new CheckPositionVO();
            BeanUtil.copyProperties(o, vo);
            //设置其他参数
            Optional.ofNullable(vo.getRobotId()).ifPresent(robotId -> {
                RobotEntity robot = robotMapper.selectById(robotId);
                if (robot != null) {
                    vo.setRobotName(robot.getName());
                }
            });
            Long posId = vo.getId();
            List<CheckPositionStandardEntity> refList = checkPositionStandardService.list(
                    Wrappers.<CheckPositionStandardEntity>lambdaQuery()
                            .eq(CheckPositionStandardEntity::getPositionId, posId)
            );
            if (CollUtil.isNotEmpty(refList)) {
                List<CheckStandardEntity> standardEntityList = checkStandardMapper.selectList(null);
                Map<Long, String> standardMap = standardEntityList.stream().collect(Collectors.toMap(CheckStandardEntity::getId, CheckStandardEntity::getName));
                vo.setCheckStandardIds(refList.stream().map(CheckPositionStandardEntity::getStandardId).collect(Collectors.toSet()));
                vo.setCheckStandardNames(
                        refList.stream()
                                .map(CheckPositionStandardEntity::getStandardId)
                                .map( id -> standardMap.get(id))
                                .collect(Collectors.toSet())
                );
            }
            return vo;
        }
        return null;
    }

    private void preCheck(CheckPositionEntity entity, Boolean update) {
        Long id = entity.getId();
        String name = entity.getName();
        if (update) {//更新操作
            Assert.notNull(id, "id不可为空！");
        } else {
            Assert.hasText(name, "name不可为空！");
        }
    }

    @Override
    public Page<CheckPositionVO> getCheckPositionPage(Page page, CheckPositionQueryDTO dto) {
        CheckPositionEntity entity = new CheckPositionEntity();
        BeanUtils.copyProperties(dto, entity);
        entity.setName(null);
        entity.setCode(null);
        final String name = dto.getName();
        final String code = dto.getCode();
        LambdaQueryWrapper<CheckPositionEntity> wrapper = new LambdaQueryWrapper<>(entity);
        wrapper.like(StringUtils.hasText(name), CheckPositionEntity::getName, name);
        wrapper.like(StringUtils.hasText(code), CheckPositionEntity::getCode, code);
        wrapper.orderByAsc(CheckPositionEntity::getId);
        return (Page<CheckPositionVO>) this.page(page, wrapper)
                .convert(this::convertToVO);
    }

    @Override
    public CheckPositionVO getCheckPositionById(Long id) {
        Assert.notNull(id, "id不可为空！");
        return convertToVO(this.getById(id));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveCheckPosition(CheckPositionSaveDTO dto) {
        CheckPositionEntity entity = new CheckPositionEntity();
        BeanUtils.copyProperties(dto, entity);
        this.preCheck(entity, false);
        //保存检测点位
        this.save(entity);
        //保存点位&标准
        Long posId = entity.getId();
        List<Long> checkStandardIds = dto.getCheckStandardIds();
        List<CheckPositionStandardEntity> saveRefList = new ArrayList<>();
        if (CollUtil.isNotEmpty(checkStandardIds)) {
            for (Long standardId : checkStandardIds) {
                saveRefList.add(new CheckPositionStandardEntity(posId, standardId));
            }
            checkPositionStandardService.saveBatch(saveRefList);
        }
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateCheckPositionById(CheckPositionUpdateDTO dto) {
        CheckPositionEntity entity = new CheckPositionEntity();
        BeanUtils.copyProperties(dto, entity);
        this.preCheck(entity, true);
        Long posId = entity.getId();
        //删除点位&标准
        checkPositionStandardService.remove(Wrappers.<CheckPositionStandardEntity>lambdaQuery()
                .eq(CheckPositionStandardEntity::getPositionId, posId));
        //保存点位&标准
        List<Long> checkStandardIds = dto.getCheckStandardIds();
        List<CheckPositionStandardEntity> saveRefList = new ArrayList<>();
        if (CollUtil.isNotEmpty(checkStandardIds)) {
            for (Long standardId : checkStandardIds) {
                saveRefList.add(new CheckPositionStandardEntity(posId, standardId));
            }
            checkPositionStandardService.saveBatch(saveRefList);
        }
        return this.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeCheckPositionBatchByIds(List<Long> ids) {
        Assert.notEmpty(ids, "ID不可为空！");
        this.removeBatchByIds(ids);
        return checkPositionStandardService.remove(Wrappers.<CheckPositionStandardEntity>lambdaQuery()
                .in(CheckPositionStandardEntity::getPositionId, ids));
    }

    @Override
    public String getMileageByRobotId(Long robotId) {
        return Math.random() + "";
    }
}